home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / compress / unzip531.zip / win32 / crc_i386.asm < prev    next >
Assembly Source File  |  1997-02-18  |  5KB  |  157 lines

  1. ; crc_i386.asm, optimized CRC calculation function for Zip and UnZip, not
  2. ; copyrighted by Paul Kienitz and Christian Spieler.  Last revised 10 Nov 96.
  3. ;
  4. ; Revised 06-Oct-96, Scott Field (sfield@microsoft.com)
  5. ;   fixed to assemble with masm by not using .model directive which makes
  6. ;   assumptions about segment alignment.  Also,
  7. ;   avoid using loop, and j[e]cxz where possible.  Use mov + inc, rather
  8. ;   than lodsb, and other misc. changes resulting in the following performance
  9. ;   increases:
  10. ;
  11. ;      unrolled loops                NO_UNROLLED_LOOPS
  12. ;      *8    >8      <8              *8      >8      <8
  13. ;
  14. ;      +54%  +42%    +35%            +82%    +52%    +25%
  15. ;
  16. ;   first item in each table is input buffer length, even multiple of 8
  17. ;   second item in each table is input buffer length, > 8
  18. ;   third item in each table is input buffer length, < 8
  19. ;
  20. ;
  21. ; FLAT memory model assumed.
  22. ;
  23. ; The loop unroolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
  24. ; This results in shorter code at the expense of reduced performance.
  25. ;
  26. ;==============================================================================
  27. ;
  28. ; Do NOT assemble this source if external crc32 routine from zlib gets used.
  29. ;
  30.     IFNDEF USE_ZLIB
  31. ;
  32.         .386p
  33.         name    crc_i386
  34. ; don't make assumptions about segment align        .model flat
  35.  
  36. extrn   _get_crc_table:near    ; ulg near *get_crc_table(void);
  37.  
  38. ;
  39.     IFNDEF NO_STD_STACKFRAME
  40.         ; Use a `standard' stack frame setup on routine entry and exit.
  41.         ; Actually, this option is set as default, because it results
  42.         ; in smaller code !!
  43. STD_ENTRY       MACRO
  44.                 push    ebp
  45.                 mov     ebp,esp
  46.         ENDM
  47.  
  48.         Arg1    EQU     08H[ebp]
  49.         Arg2    EQU     0CH[ebp]
  50.         Arg3    EQU     10H[ebp]
  51.  
  52. STD_LEAVE       MACRO
  53.                 pop     ebp
  54.         ENDM
  55.  
  56.     ELSE  ; NO_STD_STACKFRAME
  57.  
  58. STD_ENTRY       MACRO
  59.         ENDM
  60.  
  61.         Arg1    EQU     18H[esp]
  62.         Arg2    EQU     1CH[esp]
  63.         Arg3    EQU     20H[esp]
  64.  
  65. STD_LEAVE       MACRO
  66.         ENDM
  67.  
  68.     ENDIF ; ?NO_STD_STACKFRAME
  69.  
  70. ; This is the loop body of the CRC32 cruncher.
  71. ; registers modified:
  72. ;   ebx  : crc value "c"
  73. ;   esi  : pointer to next data byte "buf++"
  74. ; registers read:
  75. ;   edi  : pointer to base of crc_table array
  76. ; scratch registers:
  77. ;   eax  : requires upper three bytes of eax = 0, uses al
  78. Do_CRC  MACRO
  79.                 mov     al, byte ptr [esi]   ; al <-- *buf
  80.                 inc     esi                  ; buf++
  81.                 xor     al,bl                ; (c ^ *buf++) & 0xFF
  82.                 shr     ebx,8                ; c = (c >> 8)
  83.                 xor     ebx,[edi+eax*4]      ;  ^ table[(c ^ *buf++) & 0xFF]
  84.         ENDM
  85.  
  86. _TEXT   segment para
  87.  
  88.         public  _crc32
  89. _crc32          proc    near  ; ulg crc32(ulg crc, ZCONST uch *buf, extent len)
  90.                 STD_ENTRY
  91.                 push    edi
  92.                 push    esi
  93.                 push    ebx
  94.                 push    edx
  95.                 push    ecx
  96.  
  97.                 mov     esi,Arg2             ; 2nd arg: uch *buf
  98.                 sub     eax,eax              ;> if (!buf)
  99.                 test    esi,esi              ;>   return 0;
  100.                 jz      fine                 ;> else {
  101.  
  102.                 call    _get_crc_table
  103.                 mov     edi,eax
  104.                 mov     ebx,Arg1             ; 1st arg: ulg crc
  105.                 sub     eax,eax              ; eax=0; make al usable as a dword
  106.                 mov     ecx,Arg3             ; 3rd arg: extent len
  107.                 not     ebx                  ;>   c = ~crc;
  108.  
  109.     IFNDEF  NO_UNROLLED_LOOPS
  110.                 mov     edx,ecx              ; save len in edx
  111.                 and     edx,000000007H       ; edx = len % 8
  112.                 shr     ecx,3                ; ecx = len / 8
  113.                 jz      No_Eights
  114. ; align loop head at start of 486 internal cache line !!
  115.                 align   16
  116. Next_Eight:
  117.                 Do_CRC
  118.                 Do_CRC
  119.                 Do_CRC
  120.                 Do_CRC
  121.                 Do_CRC
  122.                 Do_CRC
  123.                 Do_CRC
  124.                 Do_CRC
  125.                 dec     ecx
  126.                 jnz     Next_Eight
  127. No_Eights:
  128.                 mov     ecx,edx
  129.  
  130.     ENDIF ; NO_UNROLLED_LOOPS
  131.                 jecxz   bail                 ;>   if (len)
  132. ; align loop head at start of 486 internal cache line !!
  133.                 align   16
  134. loupe:                                       ;>     do {
  135.                 Do_CRC                       ;        c = CRC32(c, *buf++);
  136.                 dec     ecx                  ;>     } while (--len);
  137.                 jnz     loupe
  138.  
  139. bail:                                        ;> }
  140.                 mov     eax,ebx
  141.                 not     eax                  ;> return ~c;
  142. fine:
  143.                 pop     ecx
  144.                 pop     edx
  145.                 pop     ebx
  146.                 pop     esi
  147.                 pop     edi
  148.                 STD_LEAVE
  149.                 ret
  150. _crc32          endp
  151.  
  152. _TEXT   ends
  153. ;
  154.     ENDIF ;!USE_ZLIB
  155. ;
  156. end
  157.